# coding: utf-8

# -------------------------------------------------------------------------------
# Name:         reports.py
# Description:  报表
# Author:       XiangjunZhao
# EMAIL:        2419352654@qq.com
# Date:         2019/12/25 16:01
# -------------------------------------------------------------------------------
from django.core.paginator import Paginator
from django.db.models import Sum
from rest_framework.generics import ListAPIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.HttpAutoTestService.core.builtin.functions import ms_fmt_hms
from apps.HttpAutoTestService.serializers import TestsuiteResultListSerializer, TestcaseResultSerializer
from apps.HttpAutoTestService.models import Project, Module, Api, Testsuite, Testcase, Environment, TestcaseResult, \
    TestsuiteResult

__all__ = ['SummaryReportAPIView', 'ReportListAPIView', 'TestcaseReportAPIView', 'TestsuiteReportAPIView']


class SummaryReportAPIView(APIView):
    def get(self, request, *args, **kwargs):
        environment_count = Environment.objects.filter(is_deleted=False).count()
        project_count = Project.objects.filter(is_deleted=False).count()
        module_count = Module.objects.filter(is_deleted=False).count()
        api_count = Api.objects.filter(is_deleted=False).count()
        testsuite_count = Testsuite.objects.filter(is_deleted=False).count()
        testcase_count = Testcase.objects.filter(is_deleted=False).count()
        result = {
            'environment': environment_count,
            'project': project_count,
            'module': module_count,
            'api': api_count,
            'testsuite': testsuite_count,
            'testcase': testcase_count
        }
        return Response(data=result, content_type='application/json')


class ReportListAPIView(ListAPIView):

    def get(self, request, *args, **kwargs):
        query_params = request.query_params
        page = query_params.get('page', 1)
        page_size = query_params.get('page_size', 10)
        project_list = Project.objects.filter(is_deleted=False)
        count = len(project_list)
        project_list = Paginator(project_list, page_size).get_page(page).object_list
        results = []
        for project in project_list:
            result = {
                'project': {
                    'id': project.id,
                    'name': project.name
                },
                'api': {
                    'total': 0,
                    'initial': 0,
                    'pass': 0,
                    'partial_pass': 0,
                    'fail': 0
                },
                'testsuite': {
                    'total': 0,
                    'initial': 0,
                    'pass': 0,
                    'partial_pass': 0,
                    'fail': 0
                },
                'testcase': {
                    'total': 0,
                    'initial': 0,
                    'pass': 0,
                    'fail': 0
                }
            }

            api_list = project.api.filter(is_deleted=False)
            result['api']['total'] += len(api_list)
            for api in api_list:
                testcase_total = api.testcase.filter(is_deleted=False).count()
                testcase_initial_total = api.testcase.filter(status='INITIAL', is_deleted=False).count()
                testcase_pass_total = api.testcase.filter(status='PASS', is_deleted=False).count()
                testcase_fail_total = api.testcase.filter(status='FAIL', is_deleted=False).count()
                result['testcase']['total'] += testcase_total
                result['testcase']['initial'] += testcase_initial_total
                result['testcase']['pass'] += testcase_pass_total
                result['testcase']['fail'] += testcase_fail_total

                if testcase_total == 0 or testcase_initial_total == testcase_total:
                    result['api']['initial'] += 1
                if testcase_total != 0 and testcase_pass_total == testcase_total:
                    result['api']['pass'] += 1
                if testcase_total != 0 and testcase_pass_total != testcase_total:
                    result['api']['partial_pass'] += 1
                if testcase_total != 0 and testcase_fail_total == testcase_total:
                    result['api']['fail'] += 1

            testsuite_list = project.testsuite.filter(is_deleted=False)
            result['testsuite']['total'] += len(testsuite_list)
            for testsuite in testsuite_list:
                testcase_total = testsuite.testcases.filter(is_deleted=False).count()
                testcase_initial_total = testsuite.testcases.filter(status='INITIAL', is_deleted=False).count()
                testcase_pass_total = testsuite.testcases.filter(status='PASS', is_deleted=False).count()
                testcase_fail_total = testsuite.testcases.filter(status='FAIL', is_deleted=False).count()

                if testcase_total == 0 or testcase_initial_total == testcase_total:
                    result['testsuite']['initial'] += 1
                if testcase_total != 0 and testcase_pass_total == testcase_total:
                    result['testsuite']['pass'] += 1
                if testcase_total != 0 and testcase_pass_total != testcase_total:
                    result['testsuite']['partial_pass'] += 1
                if testcase_total != 0 and testcase_fail_total == testcase_total:
                    result['testsuite']['fail'] += 1

            results.append(result)
        return Response(data={'count': count, 'results': results}, content_type='application/json')


class TestcaseReportAPIView(APIView):
    '''
    用例测试报告
    '''
    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):
        query_params = self.request.query_params
        # 版本号
        version = query_params.get('version')
        # 用例状态
        status = query_params.get('status', None)
        response_data = {}
        if version:
            testcase_results = TestcaseResult.objects.filter(version=version, is_deleted=False).order_by('execute_time')
            total = testcase_results.count()
            success = testcase_results.filter(status='PASS').count()
            fail = testcase_results.filter(status='FAIL').count()
            total_elapsed_ms = testcase_results.aggregate(total_elapsed_ms=Sum('elapsed_ms'))['total_elapsed_ms']
            total_elapsed_ms = ms_fmt_hms(total_elapsed_ms)
            try:
                success_pct = round((success / total) * 100, 2)
            except ZeroDivisionError:
                success_pct = 0
            # 根据用例状态过滤用例结果
            if status:
                testcase_results = testcase_results.filter(status=status).order_by('execute_time')
            results = []
            for item in testcase_results:
                testcase_result = TestcaseResultSerializer(item).data
                results.append(testcase_result)
            response_data = {'total': total, 'success': success, 'fail': fail, 'success_pct': success_pct,
                             'total_elapsed_ms': total_elapsed_ms, 'results': results}
        return Response(data=response_data, content_type='application/json')


class TestsuiteReportAPIView(APIView):
    '''
    场景测试报告
    '''
    permission_classes = [AllowAny]

    def get(self, request, *args, **kwargs):
        query_params = self.request.query_params
        # 版本号
        version = query_params.get('version')
        # 场景状态
        status = query_params.get('status', None)
        response_data = {}
        if version:
            testcase_results = TestcaseResult.objects.filter(version=version, testsuite_result_id__isnull=False,
                                                             is_deleted=False)
            testcase_result_total = testcase_results.count()
            testcase_result_success = testcase_results.filter(status='PASS').count()
            testcase_result_fail = testcase_results.filter(status='FAIL').count()
            total_elapsed_ms = testcase_results.aggregate(total_elapsed_ms=Sum('elapsed_ms'))['total_elapsed_ms']
            total_elapsed_ms = ms_fmt_hms(total_elapsed_ms)
            try:
                testcase_result_success_pct = round((testcase_result_success / testcase_result_total) * 100, 2)
            except ZeroDivisionError:
                testcase_result_success_pct = 0
            testsuite_results = TestsuiteResult.objects.filter(version=version, is_deleted=False).order_by(
                'execute_time')
            # 根据场景状态过滤场景结果
            if status:
                testsuite_results = testsuite_results.filter(status=status).order_by('execute_time')
            results = []
            for testsuite_result in testsuite_results:
                testsuite_result_serializer = TestsuiteResultListSerializer(testsuite_result).data
                testsuite_result_id = testsuite_result_serializer.get('id')
                total = testcase_results.filter(testsuite_result_id=testsuite_result_id).count()
                success = testcase_results.filter(testsuite_result_id=testsuite_result_id, status='PASS').count()
                fail = testcase_results.filter(testsuite_result_id=testsuite_result_id, status='FAIL').count()
                try:
                    success_pct = round((success / total) * 100, 2)
                except ZeroDivisionError:
                    success_pct = 0
                testsuite_result_serializer['total'] = total
                testsuite_result_serializer['success'] = success
                testsuite_result_serializer['fail'] = fail
                testsuite_result_serializer['success_pct'] = success_pct
                testsuite_result_serializer['testcase_result'] = []
                testcase_results_temp = testcase_results.filter(testsuite_result_id=testsuite_result_id).order_by(
                    'execute_time')
                for testcase_result in testcase_results_temp:
                    testsuite_result_serializer['testcase_result'].append(
                        TestcaseResultSerializer(testcase_result).data)
                results.append(testsuite_result_serializer)
            response_data = {'total': testcase_result_total, 'success': testcase_result_success,
                             'fail': testcase_result_fail, 'success_pct': testcase_result_success_pct,
                             'total_elapsed_ms': total_elapsed_ms, 'results': results}
        return Response(data=response_data, content_type='application/json')
